package com.yellowpage.wf.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.yellowpage.white.common.PageRender;
import com.yellowpage.white.dao.QueryAssistantSQL;
import com.yellowpage.white.service.BaseServiceImpl;
import com.yellowpage.wf.dao.ContextDao;
import com.yellowpage.wf.dao.WorkflowInstanceDao;
import com.yellowpage.wf.dao.WorkflowNodeDao;
import com.yellowpage.wf.dao.WorkflowNodeInstanceDao;
import com.yellowpage.wf.dao.WorkflowPathDao;
import com.yellowpage.wf.dao.WorklistDao;
import com.yellowpage.wf.data.WorkflowDataUtils;
import com.yellowpage.wf.data.WorkflowInstance;
import com.yellowpage.wf.data.WorkflowNode;
import com.yellowpage.wf.data.WorkflowNodeInstance;
import com.yellowpage.wf.data.Worklist;

public class WorkflowInstanceServiceImpl extends BaseServiceImpl implements WorkflowInstanceService {
	  private WorkflowInstanceDao workflowInstanceDao;
	  private WorkflowNodeInstanceDao workflowNodeInstanceDao;	  
	  private WorkflowNodeDao workflowNodeDao;
	  private WorkflowPathDao workflowPathDao;
	  private ContextDao workflowContextDao;
	  private WorklistDao worklistDao;

	  public WorkflowPathDao getWorkflowPathDao() {
		return workflowPathDao;
	}


	public void setWorkflowPathDao(WorkflowPathDao workflowPathDao) {
		this.workflowPathDao = workflowPathDao;
	}


	public WorkflowInstanceDao getWorkflowInstanceDao() {
		return workflowInstanceDao;
	}


	public ContextDao getWorkflowContextDao() {
		return workflowContextDao;
	}


	public void setWorkflowContextDao(ContextDao workflowContextDao) {
		this.workflowContextDao = workflowContextDao;
	}


	public WorklistDao getWorklistDao() {
		return worklistDao;
	}


	public void setWorklistDao(WorklistDao worklistDao) {
		this.worklistDao = worklistDao;
	}


	public WorkflowNodeInstanceDao getWorkflowNodeInstanceDao() {
		return workflowNodeInstanceDao;
	}


	public void setWorkflowNodeInstanceDao(
			WorkflowNodeInstanceDao workflowNodeInstanceDao) {
		this.workflowNodeInstanceDao = workflowNodeInstanceDao;
	}


	public WorkflowNodeDao getWorkflowNodeDao() {
		return workflowNodeDao;
	}


	public void setWorkflowNodeDao(WorkflowNodeDao workflowNodeDao) {
		this.workflowNodeDao = workflowNodeDao;
	}


	public void setWorkflowInstanceDao(WorkflowInstanceDao workflowInstanceDao) {
		  this.workflowInstanceDao = workflowInstanceDao;
	  }


	  /* White generate Method */
	  public WorkflowInstance getWorkflowInstance(Long id){
	      return workflowInstanceDao.get(id);
	  }

    public List<WorkflowInstance> getAllWorkflowInstance(){
        return workflowInstanceDao.getAll();
    }

    public List<Map> queryWorkflowInstanceByPage(Map queryMap, PageRender pageRender) {

		QueryAssistantSQL sqlAssistant = baseDao.newQueryAssistantSQL(
				"SELECT a.WORKFLOW_INSTANCE_ID , a.WORKFLOW_ID , a.name W_NAME, a.WORKFLOW_NODE_ID , a.CREATE_USER , a.CREATE_TIME , a.LAST_UPDATE_USER , a.LAST_UPDATE_TIME , a.OWNER , a.STATUS , b.NAME WORKFLOW_NAME , c.NAME WORKFLOW_NODE_NAME" +
				" FROM WF_WORKFLOW_INSTANCE a , wf_workflow b , wf_workflow_node c , wf_workflow_node_instance d " +
				" WHERE 1=1  and a.workflow_id =b.workflow_id and d.workflow_node_id = c.workflow_node_id(+)")
				    			.addCondition(" and a.WORKFLOW_INSTANCE_ID = :workflowInstanceId ")
							    			.addCondition(" and a.WORKFLOW_ID = :workflowId ")
							    			.addCondition(" and a.WORKFLOW_NODE_ID = :workflowNodeId ")
							    			.addCondition(" and a.CREATE_USER = :createUser ")
							    		    .addCondition(" and a.CREATE_TIME = to_date(:createTime ,'yyyy-MM-dd') ")
		    				    			.addCondition(" and a.LAST_UPDATE_USER = :lastUpdateUser ")
							    		    .addCondition(" and a.LAST_UPDATE_TIME = to_date(:lastUpdateTime ,'yyyy-MM-dd') ")
		    				    			.addCondition(" and a.OWNER = :owner ")
							    			.addCondition(" and a.STATUS = :status ")
							    ;
								sqlAssistant.setTail(" ORDER BY a.WORKFLOW_INSTANCE_ID DESC ");
		List<Map> resultList = sqlAssistant.query(
				baseDao.getConnection(), queryMap);

		return resultList;
	}


    public void saveWorkflowInstance(WorkflowInstance workflowInstance){
//    	QueryAssistantSQL sqlAssistant = baseDao.newQueryAssistantSQL(
//    			" select a.workflow_id,a.node_to,a.node_from from wf_workflow_path a,wf_workflow_node b " +
//    			" where a.workflow_id="+workflowInstance.getWorkflowId()+
//    			" AND  b.workflow_id = a.workflow_id " +
//    			" and  a.node_from=b.workflow_node_id" +
//    			" AND  b.type = '"+WorkflowDataUtils.NODE_TYPE_START+"'");
//		List<Map> resultList = sqlAssistant.query(baseDao.getConnection(),new HashMap());
		
		String sql = " select a.workflow_id,a.node_to,a.node_from from wf_workflow_path a,wf_workflow_node b " +
		" where a.workflow_id="+workflowInstance.getWorkflowId()+
		" AND  b.workflow_id = a.workflow_id " +
		" and  a.node_from=b.workflow_node_id" +
		" AND  b.type = '"+WorkflowDataUtils.NODE_TYPE_START+"'";
		
		List<Map> resultList = this.baseDao.query(sql, new HashMap());
		
		if(resultList==null || resultList.size()<1){
			throw new RuntimeException("The Workflow cannot Service!");
		}
		
		
		
		
		
		Map result=resultList.get(0);
		workflowInstance.setWorkflowNodeId(Long.valueOf(result.get("NODE_FROM").toString()));
		workflowInstance.setStatus(WorkflowDataUtils.WORK_STATUS_ON);
		workflowInstance.setCreateTime(new Date());
        workflowInstanceDao.save(workflowInstance);
    }

      public WorkflowInstance mergeWorkflowInstance(WorkflowInstance workflowInstance){
	      return workflowInstanceDao.mergeWorkflowInstance(workflowInstance);
	  }
    
	  public void updateWorkflowInstance(WorkflowInstance workflowInstance){
	      workflowInstanceDao.update(workflowInstance);
	  }

	  public void delete(List deleteList){
	      workflowInstanceDao.remove(deleteList);
	  }
	  
	  

		
		
		
		
		
		
		


		
		public void startWorkflowInstance(WorkflowInstance workflowInstance , String uniqueContextParamName , String uniqueContextParamValue){
			if (workflowInstance == null
					|| workflowInstance.getWorkflowId() == null)
				throw new RuntimeException("工作流ID必须设置，不可以为空");
			
			
			//这个字段是否有存在必要?
			workflowInstance.setOwner(getNextNodeOperator());
			workflowInstance.setLastUpdateTime(new Date());
			
			//创建一个新的工作流实例
			workflowInstanceDao.save(workflowInstance);
			
			
			Worklist handlerJob = new Worklist();
			handlerJob.setWorkflowNodeInstanceId(workflowInstance.getWorkflowInstanceId());
			handlerJob.setStatus("END");
			handlerJob.setHandlers(workflowInstance.getCreateUser().toString());
			this.worklistDao.save(handlerJob);
			
			//将保存全局变量的map中数据保存至数据库
			if(uniqueContextParamName != null){
				Map paramMap = new HashMap();
				paramMap.put(uniqueContextParamName, uniqueContextParamValue);
				this.workflowContextDao.saveParamsToDb(paramMap, workflowInstance.getWorkflowInstanceId());
			}
			
			//获取开始结点
			WorkflowNode node = this.workflowNodeDao.getWorkflowNodeByWorkflowIdAndType(workflowInstance.getWorkflowId().toString(), WorkflowDataUtils.NODE_TYPE_START);
			
			//创建开始结点实例
			WorkflowNodeInstance workflowNodeInstance = new WorkflowNodeInstance();
			workflowNodeInstance.setWorkflowNodeId(node.getWorkflowNodeId());
			workflowNodeInstance.setWorkflowInstanceId(workflowInstance
					.getWorkflowInstanceId());

			this.workflowNodeInstanceDao.save(workflowNodeInstance);
			
			//更新工作流实例走到哪个结点
			workflowInstance.setWorkflowNodeId(workflowNodeInstance.getWorkflowNodeId());
			workflowInstanceDao.update(workflowInstance);
		}
		
		@Deprecated
		public void startWorkflowInstance(WorkflowInstance workflowInstance) {
			if (workflowInstance == null
					|| workflowInstance.getWorkflowId() == null)
				throw new RuntimeException("工作流ID必须设置，不可以为空");
			
			
			//这个字段是否有存在必要?
			workflowInstance.setOwner(getNextNodeOperator());
			
			//创建一个新的工作流实例
			workflowInstanceDao.save(workflowInstance);
			
			
			Worklist handlerJob = new Worklist();
			handlerJob.setWorkflowNodeInstanceId(workflowInstance.getWorkflowInstanceId());
			handlerJob.setStatus("END");
			handlerJob.setHandlers(workflowInstance.getCreateUser().toString());
			this.worklistDao.save(handlerJob);
			
			//将保存全局变量的map中数据保存至数据库
			//this.workflowContextService.saveParamsToDb(paramMap, workflowInstance.getWorkflowInstanceId());
			
			//获取开始结点
			WorkflowNode node = this.workflowNodeDao.getWorkflowNodeByWorkflowIdAndType(workflowInstance.getWorkflowId().toString(), WorkflowDataUtils.NODE_TYPE_START);
			
			//创建开始结点实例
			WorkflowNodeInstance workflowNodeInstance = new WorkflowNodeInstance();
			workflowNodeInstance.setWorkflowNodeId(node.getWorkflowNodeId());
			workflowNodeInstance.setWorkflowInstanceId(workflowInstance
					.getWorkflowInstanceId());

			this.workflowNodeInstanceDao.save(workflowNodeInstance);
			
			//更新工作流实例走到哪个结点
			workflowInstance.setWorkflowNodeId(workflowNodeInstance.getWorkflowNodeId());
			workflowInstanceDao.update(workflowInstance);
			
			//走到下一个结点(即开始工作流实例后不要停留在开始结点  自动走到开始结点的下一个结点)
			//instanceNext(workflowInstance, "AUDIT_YES" , null);
		}
				
		
		protected Long getNextNodeOperator() {
			return WorkflowDataUtils.DEFAULT_OWNER;
		}

		
		protected WorkflowNode getNextNode(WorkflowNodeInstance nowNode,
				String displayname) {
			WorkflowInstance workflowInstance = this.workflowInstanceDao.get(nowNode.getWorkflowInstanceId());
			WorkflowNodeInstance workflowNodeInstance = this.workflowNodeInstanceDao.get( workflowInstance.getWorkflowNodeId());
			
			List<Long> nextNodeIds = this.workflowPathDao.getNextNode(workflowInstance
					.getWorkflowId(), workflowNodeInstance.getWorkflowNodeId() , displayname);
			
			if(nextNodeIds.isEmpty()) return null;
			
			WorkflowNode nextNode = this.workflowNodeDao.get(nextNodeIds.get(0));
			
			return nextNode;
			
			
		}





}